package soa.security.mgr.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import soa.security.Constants;
import soa.security.domain.Account;
import soa.security.domain.Applsystem;
import soa.security.domain.Department;
import soa.security.domain.Organization;
import soa.security.domain.OrganizationUnit;
import soa.security.domain.Person;
import soa.security.domain.Region;
import soa.security.domain.Applsystem.Applsystems;
import soa.security.exception.AdapterException;
import soa.security.exception.OrganizationException;
import soa.security.mgr.service.ApplsystemMgrService;
import soa.security.util.BeanUtils;
import soa.security.util.JaxbUtils;

/**
 * 
 * @author CY 2015-11-6 15:51:04
 *
 */
@Service
public class ApplsystemMgrServiceImpl extends BaseMgrServiceImpl implements ApplsystemMgrService {

	@Override
	public List<Applsystem> adapt(String xml) throws AdapterException {
		// TODO Auto-generated method stub
		try {
			Applsystems bs = JaxbUtils.xml2Object(xml, Applsystems.class);
			return bs.getApplsystem();

		} catch (Exception e) {
			if (log.isDebugEnabled())
				log.debug("格式转换错误", e);
			throw new AdapterException(AdapterException.ERROR_01);
		}
	}

	@Override
	public String unadapt(List<Applsystem> list) throws AdapterException {
		// TODO Auto-generated method stub
		try {
			Applsystems bs = new Applsystems();
			bs.addAll(list);

			return JaxbUtils.object2Xml(bs, Applsystems.class);
		} catch (Exception e) {
			if (log.isDebugEnabled())
				log.debug("格式转换错误", e);
			throw new AdapterException(AdapterException.ERROR_01);
		}
	}

	@Override
	public Applsystem findByDn(String dn) throws OrganizationException {
		// TODO Auto-generated method stub
		return applsystemDao.findByDn(dn);
	}

	@Override
	public List<Applsystem> allApplsystems(String organizationId, Map<String, Object> parameters, boolean subTree)
			throws OrganizationException {
		// TODO Auto-generated method stub
		List<Applsystem> results = new ArrayList<Applsystem>();
		try {
			validateOrganization(organizationId);

			if (subTree) {
				List<Organization> oneOrg = oneOrg(organizationId);
				for (Organization or : oneOrg) {
					results.addAll(doAllApplsystems(or.getBid(), parameters));
				}
			} else {
				results = doAllApplsystems(organizationId, parameters);
			}

		} catch (Exception e) {
			wrapException(e);
		}
		return results;
	}
	
	@Override
	public List<Applsystem> allApplsystems_region(String regionDn, Map<String, Object> parameters)
			throws OrganizationException {
		// TODO Auto-generated method stub
		List<Applsystem> results = new ArrayList<Applsystem>();
		try {
			if (StringUtils.isBlank(regionDn)) {}
				regionDn = Region.root().buildDn().toString();

			results = applsystemDao.allApplsystems(regionDn, defaultSearchScope,
					parameters);
			sortResult(results);
		} catch (Exception e) {
			wrapException(e);
		}
		return results;
	}
	
	@Override
	public List<Applsystem> allApplsystems_region_unit(String regionDn, Map<String, Object> parameters)
			throws OrganizationException {
		// TODO Auto-generated method stub
		List<Applsystem> results = new ArrayList<Applsystem>();
		try {
			if (StringUtils.isBlank(regionDn)) {}
				regionDn = Region.root().buildDn().toString();
			
			results = doAllApplsystems_region_unit(regionDn, parameters);
		} catch (Exception e) {
			wrapException(e);
		}
		return results;
	}

	protected List<Applsystem> doAllApplsystems(String organizationId, Map<String, Object> parameters) {
		List<Applsystem> results = new ArrayList<Applsystem>();

		OrganizationUnit unit = gainOrganizationUnit(organizationId, Constants.APPLSYSTEM);
		results = applsystemDao.allApplsystems(unit.getDn().toString(), defaultSearchScope, parameters);

		sortResult(results);
		return results;
	}
	
	protected List<Applsystem> doAllApplsystems_region_unit(String regionDn, Map<String, Object> parameters) {
		List<Applsystem> results = new ArrayList<Applsystem>();

		OrganizationUnit unit = gainOrganizationUnit_region(regionDn, Constants.APPLSYSTEM);
		results = applsystemDao.allApplsystems(unit.getDn().toString(), defaultSearchScope, parameters);

		sortResult(results);
		return results;
	}

	@Override
	public List<Applsystem> allApplsystems(List<Applsystem> all, List<Applsystem> allApplsystems) {
		// TODO Auto-generated method stub
		Iterator<Applsystem> iter = all.iterator();
		while (iter.hasNext()) {
			Applsystem as = iter.next();
			boolean re = true;
			for (Applsystem applsystem : allApplsystems) {
				if (as.getBid().equals(applsystem.getBid())) {
					re = false;
					break;
				}
			}

			if (re)
				iter.remove();
		}
		return all;
	}

	@Override
	public void addApplsystem(String organizationId, Applsystem applsystem) throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			if (StringUtils.isBlank(applsystem.getBid())) {
				applsystem.setBid("AP" + findMaxNumber(Applsystem.class));
			}
			validate(applsystem);
			validateOrganization(organizationId);

			OrganizationUnit unit = gainOrganizationUnit(organizationId, Constants.APPLSYSTEM);

			applsystem.setDn(applsystem.buildDn(unit.getDn()));
			applsystemDao.create(applsystem);
		} catch (Exception e) {
			wrapException(e);
		}
	}
	
	@Override
	public void addApplsystem_region(Applsystem applsystem) throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			if (StringUtils.isBlank(applsystem.getBid())) {
				applsystem.setBid("AP" + findMaxNumber(Applsystem.class));
			}
			validate(applsystem);
			
			String regionDn = Region.root().buildDn().toString();

			OrganizationUnit unit = gainOrganizationUnit_region(regionDn, Constants.APPLSYSTEM);

			applsystem.setDn(applsystem.buildDn(unit.getDn()));
			applsystemDao.create(applsystem);
		} catch (Exception e) {
			wrapException(e);
		}
	}

	private void validate(Applsystem applsystem) {
		Assert.hasText(applsystem.getBid(), "应用系统编码不能为空");
		Assert.hasText(applsystem.getSname(), "应用系统名称不能为空");

		BeanUtils.blank2Null(applsystem);
	}

	@Override
	public void addApplsystemMgr(String organizationId, Applsystem model, String accountDns)
			throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			addApplsystem(organizationId, model);

			addOrRemoveAccounts4Mgr(organizationId, model, accountDns);
		} catch (Exception e) {
			wrapException(e);
		}
	}
	
	@Override
	public void addApplsystemMgr_region(Applsystem model, String accountDns)
			throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			addApplsystem_region(model);

			addOrRemoveAccounts4Mgr_region(model, accountDns);
		} catch (Exception e) {
			wrapException(e);
		}
	}
	
	private void addOrRemoveAccounts4Mgr_region(Applsystem applsystem, String accountDns) {
		String regionDn = Region.root().buildDn().toString();
		
		OrganizationUnit unit = gainOrganizationUnit_region(regionDn, Constants.APPLSYSTEM);

		applsystem.setDn(applsystem.buildDn(unit.getDn()));
		
		// 原来的accountDns
		List<String> origs = allAccountsDns(
				findAccounts_region(regionDn, Constants.APPLSYSTEMS, applsystem.getDn().toString()));
		// form 提交的accountDns
		List<String> forms = formIds(accountDns);

		// 要增加的accountDns
		List<String> adds = addIds(origs, forms);
		// 要删除的departmentDns
		List<String> rems = removeIds(origs, forms);

		ldapAddAttrName(adds, Constants.APPLSYSTEMS, applsystem.getDn().toString());
		ldapRemoveAttrName(rems, Constants.APPLSYSTEMS, applsystem.getDn().toString());
	}
	
	private void addOrRemoveAccounts4Mgr_region(String organizationId, Applsystem applsystem, String accountDns) {
		
		OrganizationUnit unit = gainOrganizationUnit(organizationId, Constants.APPLSYSTEM);

		applsystem.setDn(applsystem.buildDn(unit.getDn()));
		
		// 原来的accountDns
		List<String> origs = allAccountsDns(
				findAccounts(organizationId, Constants.APPLSYSTEMS, applsystem.getDn().toString()));
		// form 提交的accountDns
		List<String> forms = formIds(accountDns);

		// 要增加的accountDns
		List<String> adds = addIds(origs, forms);
		// 要删除的departmentDns
		List<String> rems = removeIds(origs, forms);

		ldapAddAttrName(adds, Constants.APPLSYSTEMS, applsystem.getDn().toString());
		ldapRemoveAttrName(rems, Constants.APPLSYSTEMS, applsystem.getDn().toString());
	}

	private void addOrRemoveAccounts4Mgr(String organizationId, Applsystem applsystem, String accountDns) {
		String regionDn = Region.root().buildDn().toString();
		OrganizationUnit unit = gainOrganizationUnit_region(regionDn, Constants.APPLSYSTEM);

		applsystem.setDn(applsystem.buildDn(unit.getDn()));
		
		// 原来的accountDns
		List<String> origs = allAccountsDns(
				findAccounts(organizationId, Constants.APPLSYSTEMS, applsystem.getDn().toString()));
		// form 提交的accountDns
		List<String> forms = formIds(accountDns);

		// 要增加的accountDns
		List<String> adds = addIds(origs, forms);
		// 要删除的departmentDns
		List<String> rems = removeIds(origs, forms);

		ldapAddAttrName(adds, Constants.APPLSYSTEMS, applsystem.getDn().toString());
		ldapRemoveAttrName(rems, Constants.APPLSYSTEMS, applsystem.getDn().toString());
	}

	@Override
	public void updateApplsystem(String organizationId, Applsystem applsystem) throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			validateOrganization(organizationId);
			OrganizationUnit unit = gainOrganizationUnit(organizationId, Constants.APPLSYSTEM);
			validateApplsystem(unit.getDn().toString(), applsystem.getBid());

			Applsystem up = applsystemDao.findByPrimaryKey(unit.getDn().toString(), applsystem.getBid());
			BeanUtils.copyPropertiesWithoutNull(applsystem, up);
			applsystem = up;

			validate(applsystem);
			applsystem.setDn(applsystem.buildDn(unit.getDn()));
			applsystemDao.update(applsystem);

			super.update(organizationId, applsystem);
		} catch (Exception e) {
			wrapException(e);
		}
	}

	@Override
	public void updateApplsystemMgr(String organizationId, Applsystem model, String accountDns)
			throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			updateApplsystem(organizationId, model);

			addOrRemoveAccounts4Mgr(organizationId, model, accountDns);
		} catch (Exception e) {
			wrapException(e);
		}
	}
	
	@Override
	public void updateApplsystem_region(Applsystem applsystem) throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			String regionDn = Region.root().buildDn().toString();
			OrganizationUnit unit = gainOrganizationUnit_region(regionDn, Constants.APPLSYSTEM);
			validateApplsystem(unit.getDn().toString(), applsystem.getBid());

			Applsystem up = applsystemDao.findByPrimaryKey(unit.getDn().toString(), applsystem.getBid());
			BeanUtils.copyPropertiesWithoutNull(applsystem, up);
			applsystem = up;

			validate(applsystem);
			applsystem.setDn(applsystem.buildDn(unit.getDn()));
			applsystemDao.update(applsystem);
		} catch (Exception e) {
			wrapException(e);
		}
	}

	@Override
	public void updateApplsystemMgr_region(Applsystem model, String accountDns)
			throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			updateApplsystem_region(model);
			addOrRemoveAccounts4Mgr_region(model, accountDns);
		} catch (Exception e) {
			wrapException(e);
		}
	}
	
	@Override
	public void updateApplsystemMgr_region(String organizationId, Applsystem model, String accountDns)
			throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			updateApplsystem_region(model);
			addOrRemoveAccounts4Mgr(organizationId, model, accountDns);
		} catch (Exception e) {
			wrapException(e);
		}
	}

	@Override
	public void addApplsystemMgr_region(String organizationId, Applsystem model, String accountDns)
			throws OrganizationException {
		// TODO Auto-generated method stub
		try {
			addApplsystem_region(model);

			addOrRemoveAccounts4Mgr(organizationId, model, accountDns);
		} catch (Exception e) {
			wrapException(e);
		}
	}

}
